
// 代码题

// 一、将下面异步代码使用Promise的方式改进

// setTimeout(function () {
//   var a = 'hello'
//   setTimeout(function () {
//     var b = 'lagou'
//     setTimeout(function () {
//       var c = 'I ♥ U'
//       console.log(a + b + c)
//     }, 10)
//   }, 10)
// }, 10)

// 答
// const promiseTime = (time) => {
//   return (value) => {
//     return new Promise((resolve, reject) => {
//       setTimeout(() => {
//         resolve(value)
//       }, time)
//     })
//   }
// }

// let promise = promiseTime(2000)

// promise('hello').then((value) => promise(value + 'lagou')).then(value => {
//   console.log(value + 'I ♥ U')
// })



// 二、基于以下代码完成下面的四个练习
const fp = require('lodash/fp');
// 数据
// horsepower 马力，dollar_value价格，
const cars = [
  { name: 'Ferrart FF', horsepower: 660, dollar_value: 700000, in_stock: true },
  { name: 'Spyker C12 Zagato', horsepower: 650, dollar_value: 648000, in_stock: false },
  { name: 'Jagur XKR-S', horsepower: 550, dollar_value: 132000, in_stock: false },
  { name: 'Audi R8', horsepower: 525, dollar_value: 114200, in_stock: false },
  { name: 'Aston Martin One-77', horsepower: 750, dollar_value: 1850000, in_stock: true },
  { name: 'Pagani Huayra', horsepower: 700, dollar_value: 1300000, in_stock: false },
]

// 练习1:使用函数组合fp.flowRight()重新实现下面这个函数
// let isLastInStock = function (cars) {
//   //获取最后一条数据
//   let last_car = fp.last(cars)
//   //获取最后一条数据的in stock 属性值
//   return fp.prop('in_stock', last_car)
// }

let isLastInStock = fp.flowRight(fp.prop('in_stock'), fp.last)
console.log(isLastInStock(cars));


// 练习2:使用 fp.flowRight(), fp.prop() 和 fp.first() 获取第一个 car 的 name
let isFirstName = fp.flowRight(fp.prop('name'), fp.first)
console.log(isFirstName(cars))


// 练习3:使用帮助函数 _average 重构 averageDollarValue ，使用函数组合的方式实现 
let _average = function (xs) {
  return fp.reduce(fp.add, 0, xs) / xs.length;
} // 无需改动

// let averageDollarValue = function (cars) {
//   let dollar_values = fp.map(function (car) {
//     return car.dollar_value
//   }, cars);

//   return _average(dollar_values);
// }

let averageDollarValue = fp.flowRight(_average, fp.map(car => car.dollar_value));
console.log(averageDollarValue(cars));


// 练习4:使用 flowRight 写一个 sanitizeNames() 函数，返回一个下划线连接的小写字符串，把数组中的 name 转换为这种形式：例如：sanitizeNames(["Hello World"]) => ["hello_world"]
let _underscore = fp.replace(/\W+/g, '_'); // 无需改动，并在 sanitizeNames 中使用它

let sanitizeNames = fp.flowRight(fp.map(fp.flowRight(_underscore, fp.toLower)))
console.log(sanitizeNames(["Hello World"]))



// 三、基于下面提供的代码，完成后续的四个练习
// 练习1:使用 fp.add(x, y) 和 fp.map(f, x) 创建一个能让 functor 里的值增加的函数el
const { Maybe, Container } = require('./support.js');
let maybe = Maybe.of([5, 6, 1]);

// let ex1 = fp.flowRight(fp.map(x => fp.add(x, 1)));
// console.log(maybe.map(ex1));
let ex1 = (y) => {
  // 你需要实现的函数
  return maybe.map(fp.flowRight(fp.map(x => fp.add(x, y))))._value
}
console.log(ex1(1));


// 练习2:实现一个函数 ex2，能够使用 fp.first 获取列表的第一个元素
let xs = Container.of(['do', 'ray', 'me', 'fa', 'so', 'la', 'ti', 'do']);
let ex2 = () => {
  // 你需要实现的函数
  return xs.map(fp.flowRight(fp.first))._value
}
console.log(ex2())


// 练习3:实现一个函数 ex3 ，使用 safeProp 和 fp.first 找到 user 的名字的首字母
let safeProp = fp.curry(function (x, o) {
  return Maybe.of(o[x]);
});
let user = { id: 2, name: 'Albert' };
let ex3 = (obj) => {
  // 你需要实现的函数
  return safeProp('name', obj).map(fp.first)._value
}
console.log(ex3(user))


// 练习4:使用 Maybe 重写 ex4 ，不要有 if 语句
// let ex4 = function (n) {
//   if (n) {
//     return parseInt(n)
//   }
// }

let ex4 = (n) => {
  return Maybe.of(n).map(parseInt)._value;
}
console.log(ex4(1.25))



// 四、手写实现MyPromise源码
// 要求:尽可能还原Promise中的每一一个API，并通过注释的方式描述思路和原理。
